package midoo.server.core;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.concurrent.DefaultThreadFactory;
import midoo.common.MConfig;
import midoo.common.MService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by ajianzheng on 2015/4/10.
 *
 */
public class MServerBenchControl implements MService {
    protected static final Logger LOGGER = LoggerFactory.getLogger(MServerBenchControl.class);

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;

    @Override
    public int start(MConfig cfg) throws Exception {
        final MServerBootstrapConfig config = (MServerBootstrapConfig) cfg;

        bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("control-boss"));
        workerGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("control-worker"));

        ///
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 10)
                .option(ChannelOption.SO_REUSEADDR, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();

                pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());
                pipeline.addLast("handler", new ControlHandler());
            }
        });

        /// start
        serverBootstrap.bind(config.getHost(), config.getPort()).sync();

        return 0;
    }

    class ControlHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
            String ret = MServerBench.getInstance().handleUserEvent(s);

            ctx.writeAndFlush("roger " + s);
        }
    }

    @Override
    public void stop() {
        try {
            if (null !=bossGroup) bossGroup.shutdownGracefully().sync();
            if (null !=workerGroup) workerGroup.shutdownGracefully().sync();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

